package com.springboot.cloud.demos.feign.rest;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.ClientException;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.springboot.cloud.common.core.constant.Constant;
import com.springboot.cloud.common.core.entity.vo.Result;
import com.springboot.cloud.common.core.oss.OssUtil;
import com.springboot.cloud.common.core.util.DateUtils;
import com.springboot.cloud.common.core.util.IdGen;
import com.springboot.cloud.demos.entity.form.AlbumForm;
import com.springboot.cloud.demos.entity.po.OssPolicyResponse;
import com.springboot.cloud.demos.feign.service.AlbumService;
import jdk.nashorn.internal.runtime.logging.Logger;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

import static com.springboot.cloud.common.core.entity.vo.Result.fail;
import static com.springboot.cloud.common.core.entity.vo.Result.success;
import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;

@Slf4j
@RestController
public class MediaCenterController {
    @Resource
    private OssUtil ossUtil;

    @Value("${aliyun.oss.accessKeyId}")
    private String accessKeyId;

    @Value("${aliyun.oss.accessKeySecret}")
    private String accessKeySecret;

    @Value("${aliyun.oss.endpoint}")
    private String endpoint;

    @Value("${aliyun.oss.regionId}")
    private String regionId;

    @Value("${aliyun.oss.host}")
    private String host;

    @Value("${aliyun.oss.bucket}")
    private String defaultBucket;

    @Value("${aliyun.oss.roleArn}")
    private String roleArn;
    @Value("${aliyun.oss.tokenExpireTime}")
    private Long tokenExpireTime;
@Autowired
    private AlbumService albumService;



    @RequestMapping(value = "open/media/getOssSts")
    public Result getOssSts(String callbackFunName) throws IOException {
        // 只有 RAM用户（子账号）才能调用 AssumeRole 接口
        // 阿里云主账号的AccessKeys不能用于发起AssumeRole请求
        // 请首先在RAM控制台创建一个RAM用户，并为这个用户创建AccessKeys
        String policy = "{\n" +
                "    \"Statement\": [\n" +
                "        {\n" +
                "            \"Action\": \"oss:*\",\n" +
                "            \"Effect\": \"Allow\",\n" +
                "            \"Resource\": \"*\"\n" +
                "        }\n" +
                "    ],\n" +
                "    \"Version\": \"1\"\n" +
                "}";
        // RoleSessionName 是临时Token的会话名称，自己指定用于标识你的用户，主要用于审计，或者用于区分Token颁发给谁
        // 但是注意RoleSessionName的长度和规则，不要有空格，只能有'-' '_' 字母和数字等字符
        // 具体规则请参考API文档中的格式要求
        String roleSessionName = "alice-001";

        // 此处必须为 HTTPS
        ProtocolType protocolType = ProtocolType.HTTPS;
        OssPolicyResponse respMap = new OssPolicyResponse();
        try {
            final AssumeRoleResponse stsResponse = assumeRole(accessKeyId, accessKeySecret, roleArn, roleSessionName,
                    policy, protocolType, tokenExpireTime);


            respMap.setStatusCode("200");
            respMap.setAccessKeyId(stsResponse.getCredentials().getAccessKeyId());
            respMap.setAccessKeySecret(stsResponse.getCredentials().getAccessKeySecret());
            respMap.setSecurityToken(stsResponse.getCredentials().getSecurityToken());
            respMap.setExpiration(stsResponse.getCredentials().getExpiration());
            respMap.setHost("https://" + defaultBucket + "." + endpoint);
            respMap.setCdn(host);
        } catch (Exception e) {
            respMap.setStatusCode("500");
        }
        if (callbackFunName == null || callbackFunName.equalsIgnoreCase(""))
            return Result.success(respMap);
        else
            return Result.success(callbackFunName + "( " + respMap + " )");

    }


    protected AssumeRoleResponse assumeRole(String accessKeyId, String accessKeySecret, String roleArn,
                                            String roleSessionName, String policy, ProtocolType protocolType, long durationSeconds) throws ClientException {
        try {
            // 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求
            IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);

            // 创建一个 AssumeRoleRequest 并设置请求参数
            final AssumeRoleRequest request = new AssumeRoleRequest();
            request.setVersion("2015-04-01");
            request.setMethod(MethodType.POST);
            request.setProtocol(protocolType);

            request.setRoleArn(roleArn);
            request.setRoleSessionName(roleSessionName);
            request.setPolicy(policy);
            request.setDurationSeconds(durationSeconds);

            // 发起请求，并得到response
            final AssumeRoleResponse response = client.getAcsResponse(request);

            return response;
        } catch (ClientException e) {
            throw e;
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (com.aliyuncs.exceptions.ClientException e) {
            e.printStackTrace();
        }
        return null;
    }

    @RequestMapping(value = "/media/uploadImage")
    public Result uploadImage(HttpServletRequest request) {
        try {
            String id = IdGen.uuid();
            ServletInputStream sis = request.getInputStream();
            String url = ossUtil.uploadFile(sis, Constant.IMAGE_PATH + DateUtils.getLongDate() + id + ".png");
            return success(url);
        } catch (Exception e) {
            e.printStackTrace();
            return fail(e);
        }
    }

    @RequestMapping(value = "/media/uploadAudio")
    public Result uploadAudio(HttpServletRequest request) {
        try {
            ServletInputStream sis = request.getInputStream();
            String id = IdGen.uuid();
            String nameSuffix = ".mp3";
            String url = ossUtil.uploadFile(sis, Constant.AUDIO_PATH + DateUtils.getLongDate() + id + nameSuffix);
            return success(url);
        } catch (Exception e) {
            e.printStackTrace();
            return fail(e);
        }
    }

    @RequestMapping(value = "/media/uploadVideo")
    public Result uploadVideo(HttpServletRequest request) {
        try {
            String nameSuffix = ".mp4";
            String id = IdGen.uuid();
            ServletInputStream sis = request.getInputStream();
            String url = Constant.VIDEO_PATH + DateUtils.getLongDate() + id;
            String url2 = ossUtil.getHost() + "/" + url + ".m3u8";
            String url3 = ossUtil.uploadFile(sis, url + nameSuffix);
            if (StringUtils.isNotEmpty(url3)) {
                return success(url2);
            }
            return fail();
        } catch (Exception e) {
            e.printStackTrace();
            return fail(e);
        }
    }

    //阿里鉴黄回调，(仅针对视频)
    @RequestMapping(value = "open/osscallback")
    public Result audit(HttpServletRequest request,@RequestParam("checksum") String checksum,@RequestParam("content") String content) {
        log.info("checksum:{}",checksum);
        log.info("content:{}",content);

        JSONObject jsonObject = JSONObject.parseObject(content);
        String url= jsonObject.getString("object");
        AlbumForm albumForm =new AlbumForm();
        albumForm.setUrl(url);
        albumService.deleteByUrl(albumForm);
        return Result.success(content);
    }

}
